package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdRoleModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProductModuleVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IBusinessChangeService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ILocalProdAttrService;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.CuccProdAttrVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.LinkedProdConditionVO;
import com.iwhalecloud.bss.kite.cucc.service.scene.attr.CuccOperateInstAttrService;
import com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.module.ModifyInfoModuleHandler;
import com.iwhalecloud.bss.kite.dataservice.cache.ProdAttrCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.ProdAttr;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.service.attr.AttrData;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.common.util.StringUtil;
import com.ztesoft.zsmart.core.exception.BaseAppException;
import com.ztesoft.zsmart.core.util.JsonUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 *
 */
@RestController
@RequestMapping("/cuccProdAttr")
@Api(tags = {"/cuccProdAttr - 产品属性"})
public class LocalProdAttrController {

    @Autowired
    private ILocalProdAttrService localProdAttrService;

    @Autowired
    private IOperateSceneProdInstService operateSceneProdInstService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private IBusinessChangeService businessChangeService;

    @Autowired
    private IQuerySceneAccessProdInstService querySceneProdInstService;

    @Autowired
    private CuccOperateInstAttrService cuccOperateInstAttrService;
    
    @ApiOperation(value = "查询条件返回需要的属性列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodId", value = "产品标识",  required = true),
    @ApiImplicitParam(name = "groupId", value = "模块标识",  required = true)
    })

    @GetMapping(value = "/inst/prodConditionAttrs")
    public DataResult<LinkedProdConditionVO> listProdConditionAttrs(@RequestParam String prodId, String groupId) {
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        LinkedProdConditionVO prodConditionVO = localProdAttrService.listLinkedProdConditionAttrs(sceneInstId, prodId, groupId);
        return ErrorConsts.SUCCESS.getResult(prodConditionVO);
    }

    @ApiOperation(value = "查询更多联通产品属性实例列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodInstId", value = "产品实例标识", required = true),
        @ApiImplicitParam(name = "prodRoleId", value = "角色id", required = true)
    })
    @GetMapping(value = "/inst/more")
    public DataResult<List<CuccProdAttrVO>> listMoreProdInstAttrs(@RequestParam String prodInstId,
        @RequestParam String prodRoleId) {

        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String custId = KiteWebContext.getContext().getCustId();
        //只查询更多的属性
        List<CuccProdAttrVO> prodAttrList = localProdAttrService
            .listCuccProdInstAttrs(sceneInstId, custId, prodInstId, prodRoleId).stream().filter(cuccProdAttrVO -> {
                return KeyConsts.PROD_ATTR_SHOW_TYPE_M.equals(cuccProdAttrVO.getShowType());
            }).collect(Collectors.toList());

        return ErrorConsts.SUCCESS.getResult(prodAttrList);
    }

    @KiteTransactional
    @ApiOperation(value = "保存产品属性")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景id", required = false),
        @ApiImplicitParam(name = "custId", value = "客户id", required = false),
        @ApiImplicitParam(name = "fieldName", value = "产品属性规格编码", required = true),
        @ApiImplicitParam(name = "prodInstId", value = "产品实例标识", required = true),
        @ApiImplicitParam(name = "value", value = "产品属性值", required = true),
        @ApiImplicitParam(name = "valueDesc", value = "显示值", required = true)
    })
    @PostMapping(value = "/saveProdAttr")
    public DataResult<List<ProdAttrVO>> saveProdAttr(@RequestParam(required = false) String sceneInstId, @RequestParam(required = false) String custId,
        @RequestParam String fieldName, @RequestParam String prodInstId,
        @RequestParam String value, @RequestParam String valueDesc, @RequestParam(required = false) String extJson,
        @RequestParam(required = false) String groupId) throws BaseAppException {
        //兼容属性分组的需求
        if (KiteStringUtils.isEmpty(extJson)) {
            AttrData data = new AttrData();
            data.setPage(true);
            extJson = JsonUtil.object2Json(data);
        }
        operateSceneProdInstService
            .updateProdInstAttr(KiteWebContext.getContext().getCurrentSceneInstId(), prodInstId, fieldName, value,
                valueDesc, KiteWebContext.getContext().getCustId(), ContextUtil.getUserId().toString(), extJson);

        DataResult<List<ProdAttrVO>> result = this.listProdInstAttrs(prodInstId, groupId);

        //判断是否需要局部刷新，判断当前保存的属性是否有处理类
        String prodId = querySceneInstService.getProdInst(KiteWebContext.getContext().getCustId(), prodInstId)
            .getProdId();
        ProdAttr prodAttr = ProdAttrCache.get(prodId).stream().filter(prodAttrFile -> {
            return StringUtil.equals(prodAttrFile.getFieldName(), fieldName);
        }).findAny().orElse(null);
        if (!KiteObjectUtils.isEmpty(prodAttr) && StringUtil.isNotEmpty(prodAttr.getHandlerClass())) {
            //局部刷新
            result.setDataUpdateMsg("1");
            //业务变更,根据service_control_scope过滤
            List<ProdAttrVO> newProdAttrList = new ArrayList<ProdAttrVO>();
            List<String> serviceOffers = querySceneInstService //获取页面勾选的操作类型
                .getExtParameterValue(KiteWebContext.getContext().getCurrentSceneInstId(),
                    "BUSI_CHANGE_SERVICEOFFERID");
            List<KiteProdInst> kiteProdInsts = querySceneInstService
                .listProdInsts(KiteWebContext.getContext().getCurrentSceneInstId());
            if (KiteListUtils.isNotEmpty(serviceOffers)) {
                serviceOffers.stream().forEach(serviceOfferId -> {
                    if (KiteListUtils.isNotEmpty(kiteProdInsts)) {
                        kiteProdInsts.stream().forEach(kiteProdInst -> {
                            ProdAttrModuleVO prodAttrModule = businessChangeService
                                .dealProdAttrList(KiteWebContext.getContext().getCurrentSceneInstId(),
                                    KiteWebContext.getContext().getCustId(), kiteProdInst, serviceOfferId,
                                    new ProdAttrModuleVO());
                            if (!KiteObjectUtils.isEmpty(prodAttrModule) && KiteListUtils
                                .isNotEmpty(prodAttrModule.getProdAttrList())) {
                                List<ProdAttrVO> prodAttrVOList = prodAttrModule.getProdAttrList();
                                for (ProdAttrVO prodAttrVO : prodAttrVOList) {
                                    result.getResultObject().stream().forEach(prodAttrs -> {
                                        if (prodAttrVO.getFieldName().equals(prodAttrs.getFieldName()) && !prodAttrs
                                            .getShowType().equals(KeyConsts.PROD_ATTR_SHOW_TYPE_E)) {
                                            newProdAttrList.add(prodAttrs);
                                        }
                                    });
                                }
                            }
                        });
                    }
                });
                result.setResultObject(newProdAttrList);
            }
        }
        else {
            //只更新自己单个属性，无联动
            result.setDataUpdateMsg("0");
        }
        //todo 判断是否要全局刷新，即跨商品之间的属性联动，暂无类似的属性，等后面再行开发，可通过配置的方式
        return result;
    }

    @ApiOperation(value = "查询产品属性实例列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodInstId", value = "产品实例标识", required = true)})
    @GetMapping(value = "/inst")
    public DataResult<List<ProdAttrVO>> listProdInstAttrs(@RequestParam String prodInstId,
        @RequestParam(required = false) String groupId) {
        List<InstAttrDTO> prodInstAttrList = querySceneProdInstService
            .listSceneProdInstAttrByProdInstId(KiteWebContext.getContext().getCurrentSceneInstId(), prodInstId,
                KiteWebContext.getContext().getCustId()).getResultObject();
        List<ProdAttrVO> prodAttrList = new ArrayList<>();

        if (!KiteListUtils.isEmpty(prodInstAttrList)) {
            if (KiteStringUtils.isNotEmpty(groupId)) {
                prodInstAttrList = prodInstAttrList.stream()
                    .filter(kiteAttr -> KiteStringUtils.isEqual(groupId, kiteAttr.getGroupId()))
                    .collect(Collectors.toList());
            }

            for (InstAttrDTO kiteAttr : prodInstAttrList) {
                if (KeyConsts.PROD_ATTR_SHOW_TYPE_E.equals(kiteAttr.getShowType()) || KeyConsts.PROD_ATTR_SHOW_TYPE_H.equals(kiteAttr.getShowType()) || "98H"
                    .equals(kiteAttr.getAttrValueTypeId())) {
                    continue;
                }
                prodAttrList.add(KiteBeanUtils.transform(kiteAttr, ProdAttrVO.class));
            }
        }
        return ErrorConsts.SUCCESS.getResult(prodAttrList);
    }
    
    @ApiOperation(value = "查询起租环节产品属性")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = true)})
    @GetMapping(value = "/listProdInstStartRentAttrs")
    public DataResult<List<ProductModuleVO>> listProdInstStartRentAttrs(@RequestParam String sceneInstId) {
        List<ProductModuleVO> productModule = new ArrayList<>(); //产品信息
        List<KiteProdInst> kiteProdInsts = querySceneInstService.listProdInsts(sceneInstId);
        if (KiteListUtils.isEmpty(kiteProdInsts)) {
            return ErrorConsts.SUCCESS.getResult(productModule);
        }
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        kiteProdInsts.forEach(kiteProdInst -> {
            ProductModuleVO productModuleVO = businessChangeService.genProductVO(kiteProdInst.getProdId());
            ProdRoleModuleVO prodRoleVO = businessChangeService.genProductRoleVO(kiteProdInst);
            ProdAttrModuleVO prodAttrModule = prodAttrModule = cuccOperateInstAttrService
                .processAttrs(sceneInstId, sceneInst.getCustId(), kiteProdInst.getProdInstId(), sceneInst.getServiceOfferId(),
                    kiteProdInst.getProdId());
            if (KiteListUtils.isNotEmpty(prodAttrModule.getProdAttrList())) {
                prodRoleVO.setProdAttr(prodAttrModule);
                productModuleVO.getProdRole().add(prodRoleVO);
                productModule.add(productModuleVO);
            }
        });
        ModifyInfoModuleHandler modifyInfoModuleHandler = SpringUtil.getBean(ModifyInfoModuleHandler.class);
        modifyInfoModuleHandler.divideProdAttr(productModule, sceneInstId, sceneInst.getCustId(), false);
        return ErrorConsts.SUCCESS.getResult(productModule);
    }
}
